﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace Ecobee.Net
{
	/// <summary>
	/// Represents a list of Thermostats with their revision numbers.
	/// </summary>
	public class Thermostats : ApiObjectCollection<Thermostat>
	{
		/// <summary>
		/// Creates a new instance of Ecobee.Net.RevisionList using the specified
		/// instance of Ecobee.Net.Api.
		/// </summary>
		/// <param name="api"></param>
		public Thermostats(Api api)
			: base(api)
		{
		}

		/// <summary>
		/// Request the details of one or more thermostats.
		/// </summary>
		/// <param name="summaryRevisionList">A list of Ecobee.Net.SummaryRevision objects to have
		/// their detail requested.</param>
		/// <param name="selectionItems">A Ecobee.Net.SelectionItems object that specifies which details to request.</param>
		/// <returns></returns>
		public async Task<bool> Request(IEnumerable<SummaryRevision> summaryRevisionList, SelectionItems selectionItems)
		{
			bool returnValue = false;

			// ***
			// *** Force the selection type to Thermostats
			// ***
			Selection selection = new Selection();
			selection.SelectionType = SelectionType.Thermostats;
			selection.SelectionMatch = string.Join(",", summaryRevisionList.Select(t => t.Identifier).ToArray());
			selection.SetSelectionItems(selectionItems);

			// ***
			// *** A Thermostats object is required to request
			// *** details for one or more thermostats.
			// ***
			GetThermostatDetail thermostatUpdate = new GetThermostatDetail()
			{
				Selection = selection
			};

			// ***
			// *** Call the web service
			// ***
			ApiResult response = await this.Api.Http.Get(this.Api.KnownUri.Thermostat(thermostatUpdate));

			if (response.Successful)
			{
				if (response.DataObject.thermostatList != null)
				{
					dynamic dataObject = response.DataObject;

					if (dataObject != null)
					{
						// ***
						// *** update each thermostat
						// ***
						foreach (var item in dataObject.thermostatList)
						{
							string identifier = ((JValue)item.identifier).ToObject<string>();

							// ***
							// *** Locate the appropriate thermostat object by Identifier
							// ***
							var qry = from tbl in this.Items
									  where tbl.Identifier == identifier
									  select tbl;

							var summaryRevisions = summaryRevisionList.Where(t=>t.Identifier == identifier);

							if (summaryRevisions.Count()==1)
							{
								SummaryRevision summaryRevision = summaryRevisions.Single();
								Thermostat thermostat =null;

								if (qry.Count() == 1)
								{
									// ***
									// *** Get a reference to the thermostat object'
									// *** for convenience. Note that objects are
									// *** always updated and not re-created. This 
									// *** allows the properties to raise Property
									// *** changed events so that UI bindings (if
									// *** used) are updated appropriately
									// ***
									thermostat = qry.Single();
								}
								else
								{
									thermostat = new Thermostat(this.Api);
									this.Add(thermostat);
								}

								thermostat.Identifier = identifier;
								thermostat.Name = summaryRevision.Name;
								thermostat.Connected = summaryRevision.Connected;
								thermostat.ThermostatRevision = summaryRevision.ThermostatRevision;
								thermostat.AlertsRevision = summaryRevision.AlertsRevision;
								thermostat.RuntimeRevision = summaryRevision.RuntimeRevision;
								thermostat.ApplyDetails(selection, item);
							}
						}

						returnValue = true;
					}
				}
			}
			else
			{
				response.ThrowException();
			}

			return returnValue;
		}
	}
}
